﻿using UnityEngine;
using System.Collections;

namespace IMIForUnity
{

    public class ImiAndroidHelper
    {

        public int fd;
        public string usbPath;
        private AndroidJavaObject activityContext = null;
        private AndroidJavaObject helper = null;
        private OnPermissionGet permissionCallback;

        private static ImiAndroidHelper instance = null;

        private static MainThreadDispatcher mainThreadDispatcher;

        private static object _lock = new object();
        public static ImiAndroidHelper GetInstance()
        {
            if (instance == null)
            {
                lock (_lock)
                {
                    if (instance == null)
                    {
                        instance = new ImiAndroidHelper();
                    }
                }
            }
            return instance;
        }

        private ImiAndroidHelper()
        {
            mainThreadDispatcher = MainThreadDispatcher.GetInstance();
            fd = -1;
            usbPath = null;
        }


        /// <summary>
        /// Callback when Android Usb Permission is get/denied
        /// </summary>
        /// <param name="code"></param>
        public delegate void OnPermissionGet(ErrorCode code);

        public void RequirePermission(OnPermissionGet permissionCallback)
        {
            this.permissionCallback = permissionCallback;
            requirePermission();
        }

        public int GetAndroidAPILevel()
        {
            if (activityContext == null)
            {
                using (AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
                {
                    activityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");
                }
            }
            if (helper == null)
            {
                using (AndroidJavaClass helperClass = new AndroidJavaClass("com.hjimi.imipm.ImiUsbPermissionHelper"))
                {
                    if (helperClass != null)
                    {
                        helper = helperClass.CallStatic<AndroidJavaObject>("newInstance", activityContext);
                    }
                }
            }

            int apiLevel = helper.Call<int>("getApiLevel");
            return apiLevel;

        }

        /**
         * Permission Callback from ImiUsbPermissionHelper
         **/
        private class PermissionCallback : AndroidJavaProxy
        {
            public PermissionCallback() : base("com.hjimi.imipm.ImiUsbPermissionHelper$Callback")
            {
            }

            /**
             *  Called when get usb permission
             *  
             * _fd : fileDescriptor
             * device: UsbDevice
             *
            **/
            void onPermissionGranted(int _fd, AndroidJavaObject device)
            {
                if (instance == null)
                {
                    return;
                }
                instance.fd = _fd;
                if (device != null)
                {
                    instance.usbPath = device.Call<string>("getDeviceName");
                }
                mainThreadDispatcher.Enqueue(instance.ExecutedOnTheMainThread(ErrorCode.OK));
                Log.d("Permission Granted!" + "fd = " + instance.fd + "path = " + instance.usbPath);

            }

            /**
             * 
             * Get Usb Permission failed
             * 
             **/
            void onPermissionDenied()
            {
                if (instance == null)
                {
                    return;
                }
                mainThreadDispatcher.Enqueue(instance.ExecutedOnTheMainThread(ErrorCode.ERROR));

                Log.e("On Permission Denied!");
            }
        }

        public IEnumerator ExecutedOnTheMainThread(ErrorCode code)
        {
            if (instance.permissionCallback != null)
            {
                instance.permissionCallback(code);
            }
            yield return null;
        }



        private void requirePermission()
        {
            Debug.Log("requiring the permission!");
            if (activityContext == null)
            {
                using (AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
                {
                    activityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");
                }
            }

            if (helper == null)
            {
                using (AndroidJavaClass helperClass = new AndroidJavaClass("com.hjimi.imipm.ImiUsbPermissionHelper"))
                {
                    if (helperClass != null)
                    {
                        helper = helperClass.CallStatic<AndroidJavaObject>("newInstance", activityContext);
                        //keep the screen on
                        //No need to call it from android, call
                        //Screen.sleepTimeout = SleepTimeout.NeverSleep;
                        //helper.Call("keepScreenOn");
                    }
                }
            }

            helper.Call("requestPermission", new PermissionCallback());
        }

        /// <summary>
        /// Shutdown the device and unregister receivers
        /// </summary>
        public void shutdown()
        {
            if(helper == null)
            {
                Log.d("PermissionHelper is Null!");
                return;
            }
            helper.Call("shutdown");
        }

    }
}
